/**
 * Vue模板属性验证器
 * 用于自动检查Vue组件模板中使用的属性是否已正确定义
 */

// 创建一个全局mixin，自动为所有组件添加模板属性验证
export const TemplateValidatorMixin = {
    mounted() {
        // 仅在开发环境中进行验证
        if (process.env.NODE_ENV === 'production') {
            return;
        }

        // 简单验证模板中常见的数据绑定语法
        const validateTemplate = (vm) => {
            // 获取渲染后的HTML
            const el = vm.$el;
            if (!el || !el.outerHTML) return;

            const html = el.outerHTML;

            // 提取可能的属性名
            const extractProps = (str) => {
                // 匹配各种Vue指令和插值表达式中的变量
                const patterns = [
                    // 匹配 {{ property }} 模板插值
                    /{{([^}]+)}}/g,
                    // 匹配 v-model="property"
                    /v-model="([^"]+)"/g,
                    // 匹配 v-if="property" v-show="property"
                    /v-(if|show)="([^"]+)"/g,
                    // 匹配 v-for="item in items"
                    /v-for="[^"]*\s+in\s+([^"]+)"/g,
                    // 匹配 :attribute="property"
                    /:([^=]+)="([^"]+)"/g,
                    // 匹配 @click="method" 或 v-on:click="method"
                    /@([^=]+)="([^"]+)"|v-on:([^=]+)="([^"]+)"/g
                ];

                const props = new Set();

                patterns.forEach(pattern => {
                    const matches = [...str.matchAll(pattern)];
                    matches.forEach(match => {
                        // 取出所有捕获组
                        for (let i = 1; i < match.length; i++) {
                            if (match[i]) {
                                // 处理表达式，提取第一个可能的变量名
                                const expression = match[i].trim();
                                const firstProp = expression.split(/[\s.()[\]{}+\-*/%^&|<>=!?:,;]+/)[0];

                                // 排除JavaScript关键字和字面量
                                const keywords = ['true', 'false', 'null', 'undefined', 'this', 'new', 'function', 'if', 'else', 'return', 'var', 'let', 'const'];
                                if (firstProp && !keywords.includes(firstProp) && !firstProp.match(/^\d/)) {
                                    props.add(firstProp);
                                }
                            }
                        }
                    });
                });

                return Array.from(props);
            };

            // 提取模板中使用的属性
            const usedProps = extractProps(html);

            // 定义需要忽略的第三方组件前缀
            const ignorePrefixes = ['van-', 'el-', 'a-', 'v-', 'app']; // 常见UI库前缀和特殊组件
            // 定义需要忽略的CSS类名模式
            const ignoreCssPatterns = [/^van-/, /^el-/, /^a-/, /^v-/, /^app$/i]; // UI库CSS类名模式和特殊组件

            // 检查每个属性是否在组件中定义
            const missingProps = [];
            usedProps.forEach(prop => {
                // 忽略第三方组件前缀和UI组件
                // 首先检查是否为特殊组件名称（如App）或UI组件
                if (ignorePrefixes.some(prefix => prop.toLowerCase().startsWith(prefix.toLowerCase())) ||
                    ignoreCssPatterns.some(pattern => pattern.test(prop)) ||
                    prop.includes('-') || // 添加对包含连字符的属性的检查，这通常是UI组件
                    prop === 'App') { // 特别处理App组件
                    return;
                }

                // 检查data、computed和methods中是否存在该属性
                if (
                    (typeof vm[prop] === 'undefined') &&
                    (!vm.$options.computed || typeof vm.$options.computed[prop] === 'undefined') &&
                    (!vm.$options.methods || typeof vm.$options.methods[prop] === 'undefined') &&
                    (!vm.$options.props || !vm.$options.props[prop])
                ) {
                    missingProps.push(prop);
                }
            });

            // 输出警告
            if (missingProps.length > 0) {
                console.warn(
                    `[Vue Template Validator] 组件 ${vm.$options.name || 'Unknown'} 中有未定义的属性: ${missingProps.join(', ')}`
                );
            }
        };

        // 对当前组件进行验证
        validateTemplate(this);

        // 对子组件进行验证
        if (this.$children && this.$children.length) {
            this.$nextTick(() => {
                this.$children.forEach(child => {
                    validateTemplate(child);
                });
            });
        }
    }
};

// 安装方法 - 在main.js中使用: Vue.use(TemplateValidator)
export const TemplateValidator = {
    install(Vue) {
        Vue.mixin(TemplateValidatorMixin);
    }
};

export default TemplateValidator;